package com.resifind.www.service.impl;

import com.resifind.www.constant.CheckStatus;
import com.resifind.www.constant.ErrorCode;
import com.resifind.www.constant.RoomStatus;
import com.resifind.www.constant.TradeStatus;
import com.resifind.www.dao.OrderDao;
import com.resifind.www.dao.RoomDao;
import com.resifind.www.dao.impl.OrderDaoImpl;
import com.resifind.www.dao.impl.RoomDaoImpl;
import com.resifind.www.exception.BaseException;
import com.resifind.www.exception.MerchantException;
import com.resifind.www.exception.OrderException;
import com.resifind.www.exception.Resp;
import com.resifind.www.po.Order;
import com.resifind.www.po.Room;
import com.resifind.www.po.RoomNumber;
import com.resifind.www.service.RoomService;
import com.resifind.www.util.JdbcUtils;

import java.sql.Connection;
import java.util.List;

/**
 * @author 36069
 */
public class RoomServiceImpl implements RoomService {
    private final RoomDao roomDao = new RoomDaoImpl();
    private final OrderDao orderDao = new OrderDaoImpl();

    @Override
    public Resp<List<Room>> queryRoomByMerchantId(int merchantId) {
        List<Room> rooms = roomDao.queryRoomByMerchantId(merchantId);
        for (Room room : rooms) {
            //查询可用房间数量
            int availableRoomNumber = roomDao.queryAvailableRoomNumberByRoomId(room.getId());
            if (room.getSurplus() != availableRoomNumber) {
                //如果可用房间数量和房型数据库不一致，更新数据库
                Connection conn = null;
                try {
                    conn = JdbcUtils.getConn();
                    JdbcUtils.beginTransaction(conn);
                    boolean updateRoomResult = roomDao.updateRoomSurplusByRoomIdAndNum(room.getId(), availableRoomNumber, conn);
                    if (updateRoomResult) {
                        JdbcUtils.commitTransaction(conn);
                        room.setSurplus(availableRoomNumber);
                    } else {
                        JdbcUtils.rollbackTransaction(conn);
                        throw new BaseException(ErrorCode.DB_ERROR);
                    }
                } catch (BaseException e) {
                    throw e;
                } catch (Exception e) {
                    JdbcUtils.rollbackTransaction(conn);
                    throw new BaseException(ErrorCode.SERVER_ERROR);
                } finally {
                    JdbcUtils.closeConn(conn, null, null);
                }
            }
        }
        return Resp.success(rooms);
    }

    @Override
    public Resp<String> updateRoom(Room room) {
        Connection conn = null;
        if (room.getPrice() == null || room.getPrice() <= 0) {
            throw MerchantException.roomPriceError();
        }
        try {
            conn = JdbcUtils.getConn();
            JdbcUtils.beginTransaction(conn);
            boolean updateRoomResult = roomDao.updateRoom(room, conn);
            if (updateRoomResult) {
                JdbcUtils.commitTransaction(conn);
                return Resp.success("success");
            } else {
                JdbcUtils.rollbackTransaction(conn);
                throw new BaseException(ErrorCode.DB_ERROR);
            }
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            JdbcUtils.rollbackTransaction(conn);
            throw new BaseException(ErrorCode.SERVER_ERROR);
        } finally {
            JdbcUtils.closeConn(conn, null, null);
        }
    }

    @Override
    public Resp<String> deleteRoom(int roomId) {
        List<Order> orders = orderDao.queryOrderByRoomId(roomId);
        //检查订单是否符合删除条件
        if (deleteCondition(orders)) {
            throw OrderException.orderNotComplete();
        }
        Connection conn = null;
        try {
            conn = JdbcUtils.getConn();
            JdbcUtils.beginTransaction(conn);
            //删除房型
            boolean deleteRoomResult = roomDao.deleteRoom(roomId, conn);
            //删除订单
            boolean deleteOrderResult = true;
            if (!orders.isEmpty()) {
                deleteOrderResult = orderDao.deleteOrderByRoomId(roomId, conn);
            }
            //删除房间号
            List<RoomNumber> roomNumbers = roomDao.queryRoomNumberByRoomId(roomId);
            boolean deleteRoomNumberResult = true;
            if (!roomNumbers.isEmpty()) {
                deleteRoomNumberResult = roomDao.deleteRoomNumberByRoomId(roomId, conn);
            }
            if (deleteRoomResult && deleteOrderResult && deleteRoomNumberResult) {
                JdbcUtils.commitTransaction(conn);
                return Resp.success("success");
            } else {
                JdbcUtils.rollbackTransaction(conn);
                throw new BaseException(ErrorCode.DB_ERROR);
            }
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            JdbcUtils.rollbackTransaction(conn);
            throw new BaseException(ErrorCode.SERVER_ERROR);
        } finally {
            JdbcUtils.closeConn(conn, null, null);
        }
    }

    @Override
    public Resp<String> addRoom(int merchantId, Room room) {
        if (room.getPrice() == null || room.getPrice() <= 0) {
            throw MerchantException.roomPriceError();
        }
        Connection conn = null;
        try {
            conn = JdbcUtils.getConn();
            JdbcUtils.beginTransaction(conn);
            boolean addRoomResult = roomDao.addRoom(merchantId, room, conn);
            if (addRoomResult) {
                JdbcUtils.commitTransaction(conn);
                return Resp.success("success");
            } else {
                JdbcUtils.rollbackTransaction(conn);
                throw new BaseException(ErrorCode.DB_ERROR);
            }
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            JdbcUtils.rollbackTransaction(conn);
            throw new BaseException(ErrorCode.SERVER_ERROR);
        } finally {
            JdbcUtils.closeConn(conn, null, null);
        }
    }

    @Override
    public Resp<String> addRoomNumbers(int roomId, String numbers) {
        //检查房间号是否为空
        if (numbers == null || numbers.isEmpty()) {
            throw MerchantException.roomNumError();
        }
        Connection conn = null;
        try {
            conn = JdbcUtils.getConn();
            JdbcUtils.beginTransaction(conn);
            boolean addRoomNumberResult = roomDao.addRoomNumbers(roomId, numbers, conn);
            if (addRoomNumberResult) {
                JdbcUtils.commitTransaction(conn);
                return Resp.success("success");
            } else {
                JdbcUtils.rollbackTransaction(conn);
                throw new BaseException(ErrorCode.DB_ERROR);
            }
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            JdbcUtils.rollbackTransaction(conn);
            throw new BaseException(ErrorCode.SERVER_ERROR);
        } finally {
            JdbcUtils.closeConn(conn, null, null);
        }
    }

    @Override
    public Resp<List<RoomNumber>> queryRoomNumberByRoomId(int roomId) {
        List<RoomNumber> roomNumbers = roomDao.queryRoomNumberByRoomId(roomId);
        return Resp.success(roomNumbers);
    }

    @Override
    public Resp<String> switchRoomNumberStatus(int roomNumberId) {
        //查询房间号状态
        RoomNumber roomNumber = roomDao.queryRoomNumberByRoomNumberId(roomNumberId);
        Connection conn = null;
        try {
            conn = JdbcUtils.getConn();
            JdbcUtils.beginTransaction(conn);
            boolean updateRoomNumberResult = false;
            if (roomNumber.getStatus().equals(RoomStatus.AVAILABLE)) {
                //如果房间号状态为可用，修改为不可用
                updateRoomNumberResult = roomDao.updateRoomNumberStatus(roomNumberId, RoomStatus.UNAVAILABLE, conn);
            } else if (roomNumber.getStatus().equals(RoomStatus.UNAVAILABLE)) {
                //如果房间号状态为不可用，检查是否有订单使用该房间号
                List<Order> orders = orderDao.queryOrderByRoomNumberId(roomNumberId);
                if (deleteCondition(orders)) {
                    throw OrderException.orderNotComplete();
                }
                //修改房间号状态为可用
                updateRoomNumberResult = roomDao.updateRoomNumberStatus(roomNumberId, RoomStatus.AVAILABLE, conn);
            }
            if (updateRoomNumberResult) {
                JdbcUtils.commitTransaction(conn);
                return Resp.success("success");
            } else {
                JdbcUtils.rollbackTransaction(conn);
                throw new BaseException(ErrorCode.DB_ERROR);
            }
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            JdbcUtils.rollbackTransaction(conn);
            throw new BaseException(ErrorCode.SERVER_ERROR);
        } finally {
            JdbcUtils.closeConn(conn, null, null);
        }
    }

    @Override
    public Resp<String> deleteRoomNumber(int roomNumberId) {
        //查询房间号
        RoomNumber roomNumber = roomDao.queryRoomNumberByRoomNumberId(roomNumberId);
        List<Order> orders = orderDao.queryOrderByRoomNumberId(roomNumberId);
        if (roomNumber.getStatus().equals(RoomStatus.UNAVAILABLE)) {
            //如果房间号状态为不可用，检查是否有订单使用该房间号
            if (deleteCondition(orders)) {
                throw OrderException.orderNotComplete();
            }
        }
        Connection conn = null;
        try {
            conn = JdbcUtils.getConn();
            JdbcUtils.beginTransaction(conn);
            boolean deleteRoomNumberResult = roomDao.deleteRoomNumber(roomNumberId, conn);
            //删除该房间号的订单
            boolean deleteOrderResult = true;
            if (!orders.isEmpty()) {
                deleteOrderResult = orderDao.deleteOrderByRoomNumberId(roomNumberId, conn);
            }
            if (deleteRoomNumberResult && deleteOrderResult) {
                JdbcUtils.commitTransaction(conn);
                return Resp.success("success");
            } else {
                JdbcUtils.rollbackTransaction(conn);
                throw new BaseException(ErrorCode.DB_ERROR);
            }
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            JdbcUtils.rollbackTransaction(conn);
            throw new BaseException(ErrorCode.SERVER_ERROR);
        } finally {
            JdbcUtils.closeConn(conn, null, null);
        }
    }

    private static boolean deleteCondition(List<Order> orders) {
        if (!orders.isEmpty()) {
            for (Order order : orders) {
                //(已支付&&(!已退房))||退款中||未付款
                boolean flag = (order.getTradeStatus().equals(TradeStatus.PAID) && !order.getCheckStatus().equals(CheckStatus.CHECKED_OUT))
                        || order.getTradeStatus().equals(TradeStatus.REFUNDING)
                        || order.getTradeStatus().equals(TradeStatus.UNPAID);
                if (flag) {
                    //有已支付但不是已退房, 或退款中/未付款的订单，不允许删除
                    return true;
                }
            }
        }
        return false;
    }
}
